const express = require('express');
const router = express.Router();
const crypto = require('crypto');
const { apiLimiter, validateSignature } = require('../middlewares/security');
const { validateCity, validateTimeFormat, xssFilter } = require('../middlewares/validation');
const config = require('../config/wechat');
const db = require('../models');
const pushService = require('../services/pushService');

// 微信服务器验证
router.get('/', (req, res) => {
  const { signature, timestamp, nonce, echostr } = req.query;
  
  // 增强日志记录
  const logger = require('../utils/logger');
  logger.info('微信验证请求', {
    url: req.originalUrl,
    query: req.query,
    headers: req.headers
  });

  // 测试模式：直接通过验证
  if (process.env.NODE_ENV === 'development') {
    logger.debug('开发模式：跳过微信签名验证');
    return res.send(echostr || 'test123');
  }

  // 测试连接接口
  if (req.query.test === '1') {
    logger.debug('测试连接请求');
    return res.json({ 
      code: 200, 
      message: '连接成功',
      data: {
        serverTime: new Date().toISOString(),
        version: require('../package.json').version
      }
    });
  }

  if (!signature || !timestamp || !nonce || !echostr) {
    return res.status(400).send('缺少必要参数');
  }

  // 正式环境验证签名
  const token = config.token;
  const tmpArr = [token, timestamp, nonce].sort();
  const tmpStr = tmpArr.join('');
  const sha1 = crypto.createHash('sha1').update(tmpStr).digest('hex');

  if (sha1 === signature) {
    console.log('微信验证成功');
    res.send(echostr);
  } else {
    console.log('微信验证失败');
    res.status(403).send('验证失败');
  }
});

// 接收用户消息
router.post('/', async (req, res) => {
  const { ToUserName, FromUserName, CreateTime, MsgType, Content } = req.body;
  
  // 记录接收到的消息
  const logger = require('../utils/logger');
  logger.info('收到微信消息', {
    ToUserName,
    FromUserName,
    CreateTime,
    MsgType,
    Content,
    headers: req.headers
  });

  try {
    // 保存用户信息
    const [user, created] = await db.User.findOrCreate({
      where: { openid: FromUserName },
      defaults: {
        openid: FromUserName,
        subscribeTime: new Date(CreateTime * 1000),
        status: 1
      }
    });

    logger.debug('用户信息处理', { 
      userId: user.id,
      isNewUser: created,
      openid: FromUserName
    });

    // 处理不同类型的消息
    switch(MsgType) {
      case 'text':
        // 处理文本消息
        await handleTextMessage(user, Content);
        break;
      case 'event':
        // 处理事件消息
        await handleEventMessage(user, req.body.Event);
        break;
      default:
        // 其他类型消息
        replyTextMessage(FromUserName, ToUserName, '暂不支持此类型消息');
    }
    
    res.send('success');
  } catch (err) {
    console.error('处理微信消息失败:', err);
    res.send('success'); // 即使出错也返回success，避免微信服务器重试
  }
});

// 处理文本消息
async function handleTextMessage(user, content) {
  // 示例：用户发送城市名称，订阅天气推送
  // if (/^(订阅|取消订阅)/.test(content)) {
  //   const city = content.replace(/^(订阅|取消订阅)/, '').trim();
  //   if (city) {
  //     await handleSubscription(user, city, content.startsWith('订阅'));
  //   }
  // }
}

// 处理事件消息
async function handleEventMessage(user, event) {
  // switch(event) {
  //   case 'subscribe':
  //     // 用户关注事件
  //     await user.update({ status: 1 });
  //     break;
  //   case 'unsubscribe':
  //     // 用户取消关注事件
  //     await user.update({ status: 0 });
  //     break;
  // }
}

// 处理订阅/取消订阅
async function handleSubscription(user, city, isSubscribe) {
  const [subscription, created] = await db.Subscription.findOrCreate({
    where: { userId: user.id, cityName: city },
    defaults: {
      userId: user.id,
      cityName: city,
      pushTime: '08:00',
      weatherEnabled: isSubscribe,
      trafficEnabled: false,
      status: 1
    }
  });

  if (!created) {
    await subscription.update({ 
      weatherEnabled: isSubscribe,
      status: 1
    });
  }

  const reply = isSubscribe ? `已成功订阅${city}天气推送` : `已取消${city}天气推送`;
  replyTextMessage(user.openid, config.appId, reply);
}

function replyTextMessage(toUser, fromUser, content) {
  const xml = `
    <xml>
      <ToUserName><![CDATA[${toUser}]]></ToUserName>
      <FromUserName><![CDATA[${fromUser}]]></FromUserName>
      <CreateTime>${Math.floor(Date.now() / 1000)}</CreateTime>
      <MsgType><![CDATA[text]]></MsgType>
      <Content><![CDATA[${content}]]></Content>
    </xml>
  `;
  
  // 这里需要实现发送消息的逻辑
  // 实际项目中可能需要调用微信API或保存到数据库由定时任务发送
}





// H5订阅页面(废弃暂时不用)
router.get('/subscription', async (req, res) => {
  try {
    const { code } = req.query;
    
    if (!code) {
      // 未授权，重定向到微信授权页面
      const redirectUri = encodeURIComponent(`${config.server.baseUrl}/wechat/subscription`);
      const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${config.wechat.appId}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect`;
      return res.redirect(authUrl);
    }
    
    // 已授权，获取openid
    const openid = await wechatService.getOpenidByCode(code);
    
    // 获取JS-SDK签名
    const currentUrl = `${config.server.baseUrl}${req.originalUrl}`;
    const signature = await wechatService.getJsapiSignature(currentUrl);
    
    // 渲染页面并传递参数
    res.render('wechat/subscription', { 
      openid,
      appId: config.appId,
      timestamp: signature.timestamp,
      nonceStr: signature.nonceStr,
      signature: signature.signature
    });
  } catch (err) {
    console.error('处理微信授权失败:', err);
    res.status(500).send('页面加载失败');
  }
});



// 微信服务号H5页面(废弃暂时不用)
router.get('/vxpushview', async (req, res) => {
  try {
    const { code } = req.query;
    
    if (!code) {
      // 未授权，重定向到微信授权页面
      const redirectUri = encodeURIComponent(`${config.server.baseUrl}/wechat/vxpushview`);
      const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${config.appId}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect`;
      return res.redirect(authUrl);
    }
    
    // 已授权，获取openid
    const openid = await wechatService.getOpenidByCode(code);
    
    // 获取JS-SDK签名
    const currentUrl = `${config.server.baseUrl}${req.originalUrl}`;
    const signature = await wechatService.getJsapiSignature(currentUrl);
    
    // 渲染H5页面
    res.render('wechat/vxpushview', {
      openid,
      appId: signature.appId,
      timestamp: signature.timestamp,
      nonceStr: signature.nonceStr,
      signature: signature.signature
    });
  } catch (err) {
    console.error('加载微信H5页面失败:', err);
    res.status(500).send('页面加载失败');
  }
});

// JS-SDK签名接口
router.get('/jsapi-signature', async (req, res) => {
  try {
    const { url } = req.query;
    if (!url) {
      return res.status(400).json({ code: 400, message: '缺少url参数' });
    }
    
    const signature = await wechatService.getJsapiSignature(url);
    res.json({ code: 200, data: signature });
  } catch (err) {
    console.error('获取JS-SDK签名失败:', err);
    res.status(500).json({ code: 500, message: '获取签名失败' });
  }
});

// 获取用户订阅数据
router.get('/subscription', 
    apiLimiter,
    validateSignature,
    async (req, res) => {
  try {
    const { openid } = req.query;
    if (!openid) {
      return res.status(400).json({ code: 400, message: '缺少openid参数' });
    }

    // 查找用户订阅数据
    const user = await db.User.findOne({ 
      where: { openid },
      include: [{
        model: db.Subscription,
        as: 'subscriptions'
      }]
    });

    if (!user) {
      return res.json({ code: 404, message: '用户不存在' });
    }

    // 返回最新的订阅数据
    const subscription = user.subscriptions[0] || {};
    res.json({ 
      code: 200, 
      data: {
        province: '',
        city: subscription.cityName || '',
        weatherEnabled: subscription.weatherEnabled || false,
        trafficEnabled: subscription.trafficEnabled || false,
        pushTime: subscription.pushTime || '08:00',
        customContent: subscription.customContent || ''
      }
    });
  } catch (err) {
    console.error('获取订阅数据失败:', err);
    res.status(500).json({ code: 500, message: '服务器错误' });
  }
});

// 获取推送历史
router.get('/push-history', async (req, res) => {
  try {
    const { openid } = req.query;
    if (!openid) {
      return res.status(400).json({ code: 400, message: '缺少openid参数' });
    }

    // 查找用户
    const user = await db.User.findOne({ 
      where: { openid },
      include: [{
        model: db.PushRecord,
        as: 'PushRecords',
        limit: 15, // 限制最多15条记录
        order: [['pushTime', 'DESC']],
        include: [{
          model: db.Subscription,
          as: 'Subscription'
        }]
      }]
    });

    if (!user) {
      return res.json({ code: 404, message: '用户不存在' });
    }

    // 格式化返回数据
    const history = user.PushRecords ? user.PushRecords.map(record => ({
      id: record.id,
      type: record.pushType,
      time: record.pushTime,
      content: record.content,
      status: record.status,
      city: record.Subscription?.cityName || ''
    })) : [];

    res.json({ code: 200, data: history });
  } catch (err) {
    console.error('获取推送历史失败:', err);
    res.status(500).json({ code: 500, message: '服务器错误' });
  }
});


// 获取用户设置接口
router.get('/user-settings', async (req, res) => {
    try {
        const openid = req.query.openid || 'test_user';
        
        const user = await db.User.findOne({
            where: { openid },
            attributes: ['pushEnabled', 'quietHoursEnabled', 'quietHoursStart', 'quietHoursEnd']
        });

        if (!user) {
            return res.json({ 
                code: 404, 
                message: '用户不存在'
            });
        }

        res.json({ 
            code: 200, 
            data: {
                pushEnabled: user.pushEnabled,
                quietHoursEnabled: user.quietHoursEnabled,
                quietHoursStart: user.quietHoursStart,
                quietHoursEnd: user.quietHoursEnd
            }
        });
    } catch (err) {
        console.error('获取用户设置失败:', err);
        res.status(500).json({ 
            code: 500, 
            message: '获取用户设置失败',
            error: err.message 
        });
    }
});

// 保存账号设置接口
router.post('/save-settings', async (req, res) => {
    try {
        const { pushEnabled, quietHoursEnabled,quietHoursStart, quietHoursEnd } = req.body;
        const openid = req.query.openid || 'test_user'; // 测试用
        // 更新用户设置
        await db.User.update({
            pushEnabled,
            quietHoursEnabled,
            quietHoursStart: req.body.quietHoursStart || '23:00',
            quietHoursEnd: req.body.quietHoursEnd || '07:00'
        }, {
            where: { openid }
        });

        res.json({ 
            code: 200, 
            message: '设置保存成功',
            data: {
              pushEnabled,
              quietHoursEnabled,
              quietHoursStart,
              quietHoursEnd
            }
        });
    } catch (err) {
        console.error('保存设置失败:', err);
        res.status(500).json({ 
            code: 500, 
            message: '保存设置失败',
            error: err.message 
        });
    }
});

// 获取城市数据接口
router.get('/city-data', (req, res) => {
    try {
        const cityData = require('../config/city_data');
        if (!cityData || !cityData.provinces) {
            console.error('城市数据格式错误:', cityData);
            return res.status(500).json({ 
                code: 500, 
                message: '城市数据格式错误' 
            });
        }
        
        res.json({
            code: 200,
            data: {
                provinces: cityData.provinces
            }
        });
    } catch (err) {
        console.error('获取城市数据失败:', err);
        res.status(500).json({ 
            code: 500, 
            message: '获取城市数据失败',
            error: err.message 
        });
    }
});


// 测试推送接口（仅开发环境可用）
router.post('/test-push', async (req, res) => {
  // 生产环境禁用
  if (process.env.NODE_ENV === 'production') {
    return res.status(403).json({ 
      code: 403, 
      message: '测试接口在生产环境已禁用' 
    });
  }

  try {
    const { openid, city } = req.body;
    
    // 增强参数验证
    if (!openid || !city) {
      return res.status(400).json({ 
        code: 400, 
        message: '缺少必要参数',
        required: ['openid', 'city']
      });
    }

    // 记录测试请求
    logger.info('测试推送请求', {
      openid: Encryption.hash(openid), // 记录哈希后的openid
      city,
      ip: req.ip
    });

    await pushService.testPush(openid, city);
    res.json({ 
      code: 200, 
      message: '测试推送成功',
      warning: '此接口仅用于开发测试'
    });
  } catch (err) {
    logger.error('测试推送失败', {
      error: err.message,
      stack: err.stack
    });
    res.status(500).json({ 
      code: 500, 
      message: '测试推送失败',
      error: process.env.NODE_ENV === 'development' ? err.message : null
    });
  }
});

// 测试订阅接口（仅开发环境可用）
router.post('/test-subscribe', async (req, res) => {
  // 生产环境禁用
  if (process.env.NODE_ENV === 'production') {
    return res.status(403).json({ 
      code: 403, 
      message: '测试接口在生产环境已禁用'
    });
  }

  try {
    const { city, pushTime } = req.body;
    
    // 增强参数验证
    if (!city || !pushTime) {
      return res.status(400).json({ 
        code: 400, 
        message: '缺少必要参数',
        required: ['city', 'pushTime']
      });
    }

    // 验证时间格式
    if (!/^([01]\d|2[0-3]):([0-5]\d)$/.test(pushTime)) {
      return res.status(400).json({ 
        code: 400, 
        message: '推送时间格式应为HH:mm' 
      });
    }

    // 创建测试用户
    const [user] = await db.User.findOrCreate({
      where: { openid: 'test_user' },
      defaults: {
        openid: 'test_user',
        subscribeTime: new Date(),
        status: 1
      }
    });

    // 创建测试订阅记录
    const subscription = await db.Subscription.create({
      userId: user.id,
      cityName: city,
      cityCode: city.replace(/市$/, ''),
      pushTime: pushTime,
      weatherEnabled: services.includes('weather'),
      trafficEnabled: services.includes('traffic'),
      newsEnabled: services.includes('news'),
      tipsEnabled: services.includes('tips'),
      customContent: customTags.join(','),
      status: 1
    });

    res.json({ 
      code: 200, 
      message: '测试订阅成功',
      data: subscription
    });
  } catch (err) {
    console.error('测试订阅失败:', err);
    res.status(500).json({ code: 500, message: '测试订阅失败' });
  }
});


// 正式推送接口
router.post('/official-push', 
  apiLimiter, // 限制每分钟10次请求
  validateSignature, // 请求签名验证
  xssFilter(), // XSS防护
  async (req, res) => {
    try {
      const { userId } = req.body;
      
      if (!userId) {
        return res.status(400).json({ 
          code: 400, 
          message: '缺少必要参数',
          required: ['userId']
        });
      }

      // 执行推送
      await pushService.sendOfficialPush(userId);
      
      res.json({ 
        code: 200, 
        message: '推送请求已接收',
        data: {
          timestamp: new Date().toISOString()
        }
      });
    } catch (err) {
      logger.error('推送请求处理失败', {
        error: err.message,
        stack: err.stack
      });
      res.status(500).json({ 
        code: 500, 
        message: '推送处理失败',
        error: process.env.NODE_ENV === 'development' ? err.message : null
      });
    }
  }
);

// 正式订阅接口（带完整安全防护）使用vxpushview这个文件接口TODO::
router.post('/subscription', 
  apiLimiter, // 限制每分钟100次请求
  validateSignature, // 请求签名验证
  xssFilter(), // XSS防护
  async (req, res) => {
    try {
      const { openid, province, city, services = [], pushTime = '08:00', customTags = [], templateType = 'default' } = req.body;
      
      // 增强参数验证
      const requiredParams = ['openid', 'province', 'city'];
      const missingParams = requiredParams.filter(param => !req.body[param]);
      if (missingParams.length > 0) {
        return res.status(400).json({ 
          code: 400, 
          message: '缺少必要参数',
          missing: missingParams
        });
      }

      // 验证城市有效性
      const cityData = require('../config/city_data');
      const provinceData = cityData.provinces.find(p => p.name === province);
      if (!provinceData) {
        return res.status(400).json({ 
          code: 400, 
          message: '无效的省份名称' 
        });
      }
      
      const cityValid = provinceData.cities.some(c => c.name === city);
      if (!cityValid) {
        return res.status(400).json({ 
          code: 400, 
          message: '该省份下不存在指定城市' 
        });
      }

      // 验证推送时间格式
      if (!/^([01]\d|2[0-3]):([0-5]\d)$/.test(pushTime)) {
        return res.status(400).json({ 
          code: 400, 
          message: '推送时间格式应为HH:mm' 
        });
      }

      // 验证服务类型
      const validServices = ['weather', 'traffic', 'news', 'tips'];
      const invalidServices = services.filter(s => !validServices.includes(s));
      if (invalidServices.length > 0) {
        return res.status(400).json({ 
          code: 400, 
          message: '包含无效的服务类型',
          invalidServices
        });
      }

    // 查找或创建用户
    const [user] = await db.User.findOrCreate({
      where: { openid },
      defaults: {
        openid,
        subscribeTime: new Date(),
        status: 1
      }
    });

    // 创建或更新订阅
    const [subscription] = await db.Subscription.findOrCreate({
      where: { userId: user.id, cityName: city },
      defaults: {
        userId: user.id,
        cityCode: city, // 实际应使用城市编码
        cityName: city,
        pushTime: pushTime || '08:00',
        weatherEnabled: services.includes('weather'),
        trafficEnabled: services.includes('traffic'),
        customContent: customTags.join(','),
        status: 1
      }
    });

    // 更新定时任务
    require('../services/scheduleService').createSchedule(subscription);

    res.json({ code: 200, message: '订阅成功' });
  } catch (err) {
    console.error('处理订阅请求失败:', err);
    res.status(500).json({ code: 500, message: '服务器错误' });
  }
});

module.exports = router;